﻿using System.Drawing;
using System.Linq;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using AForge.Imaging;
using ImageProcessor.Shared;
using ImageProcessor.Shared.ImageExtensions;

namespace ImageProcessor.Tim
{
    public class RGBHistogramVM : ImageProcessorBaseVM
    {
        public RGBHistogramVM(MainViewModel mainVM) : base(mainVM)
        {

        }

        private PointCollection greenColorHistogramPoints;
        private PointCollection luminanceHistogramPoints;
        private PointCollection redColorHistogramPoints;
        private PointCollection blueColorHistogramPoints;

        public PointCollection LuminanceHistogramPoints
        {
            get
            {
                return this.luminanceHistogramPoints;
            }
            set
            {
                if (this.luminanceHistogramPoints != value)
                {
                    this.luminanceHistogramPoints = value;
                    OnPropertyChanged("LuminanceHistogramPoints");
                }
            }
        }

        public PointCollection RedColorHistogramPoints
        {
            get
            {
                return this.redColorHistogramPoints;
            }
            set
            {
                if (this.redColorHistogramPoints != value)
                {
                    this.redColorHistogramPoints = value;
                    OnPropertyChanged("RedColorHistogramPoints");                
                }
            }
        }

        public PointCollection GreenColorHistogramPoints
        {
            get
            {
                return this.greenColorHistogramPoints;
            }
            set
            {
                if (this.greenColorHistogramPoints != value)
                {
                    this.greenColorHistogramPoints = value;
                    OnPropertyChanged("GreenColorHistogramPoints");                    
                }
            }
        }

        public PointCollection BlueColorHistogramPoints
        {
            get
            {
                return this.blueColorHistogramPoints;
            }
            set
            {
                if (this.blueColorHistogramPoints != value)
                {
                    this.blueColorHistogramPoints = value;
                    OnPropertyChanged("BlueColorHistogramPoints");                
                }
            }
        }

        protected override void Execute(object obj)
        {
            var bitmap = ((BitmapSource) MainVM.SourceImage).BitmapSourceToBitmap();

            Bitmap bmp = new Bitmap(bitmap);
            // Luminance
            ImageStatisticsHSL hslStatistics = new ImageStatisticsHSL(bmp);
            int[] luminanceValues = hslStatistics.Luminance.Values;
            // RGB
            ImageStatistics rgbStatistics = new ImageStatistics(bmp);
            int[] redValues = rgbStatistics.Red.Values;
            int[] greenValues = rgbStatistics.Green.Values;
            int[] blueValues = rgbStatistics.Blue.Values;

            LuminanceHistogramPoints = ConvertToPointCollection(luminanceValues);
            RedColorHistogramPoints = ConvertToPointCollection(redValues);
            GreenColorHistogramPoints = ConvertToPointCollection(greenValues);
            BlueColorHistogramPoints = ConvertToPointCollection(blueValues);
        }

        protected override bool CanExecute(object obj)
        {
            return MainVM.SourceImage != null;
        }

        private PointCollection ConvertToPointCollection(int[] values)
        {
            int max = values.Max();

            PointCollection points = new PointCollection();
            // first point (lower-left corner)
            points.Add(new System.Windows.Point(0, max));
            // middle points
            for (int i = 0; i < values.Length; i++)
            {
                points.Add(new System.Windows.Point(i, max - values[i]));
            }
            // last point (lower-right corner)
            points.Add(new System.Windows.Point(values.Length - 1, max));

            return points;
        }
    }
}